from template import Agent
import random

TRADSEQ = 1
HOTBSEQ = 2
MULTSEQ = 3

class myAgent(Agent):
    def __init__(self, _id):
        super().__init__(_id)
        # 10x10中心价值矩阵
        self.center_bonus = [
            [0,4,0,0,0,0,0,0,4,0],
            [4,4,1,2,2,2,2,1,4,4],
            [0,1,3,3,3,3,3,3,1,0],
            [0,2,3,5,5,5,5,3,2,0],
            [0,2,3,5,7,7,5,3,2,0],
            [0,2,3,5,7,7,5,3,2,0],
            [0,2,3,5,5,5,5,3,2,0],
            [0,1,3,3,3,3,3,3,1,0],
            [4,4,1,2,2,2,2,1,4,4],
            [0,4,0,0,0,0,0,0,4,0]
        ]

    def SelectAction(self, actions, game_state):
        best_score = -float('inf')
        best_action = None
        team = game_state.agents[self.id].colour
        opp_team = 'r' if team == 'b' else 'b'
        chips = game_state.board.chips
        
        for action in actions:
            if not action or 'coords' not in action or action['coords'] is None:
                continue

            x, y = action['coords']
            
            # 坐标合法性验证
            if not (0 <= x <= 9 and 0 <= y <= 9):
                continue
                
            score = 0
            
            if action['type'] == 'place':
                # 战略位置价值
                score += self.center_bonus[y][x] * 4
                
                # 长期潜力评估
                score += self.evaluate_potential(chips, x, y, team) * 60
                score -= self.evaluate_potential(chips, x, y, opp_team) * 40
                
                # 直接序列奖励
                seq_bonus = {
                    TRADSEQ: 300,
                    MULTSEQ: 600,
                    HOTBSEQ: 200
                }.get(action.get('new_seq'), 0)
                # print(f"Action: {action}, Sequence Bonus: {seq_bonus}")
                score += seq_bonus
                
                # 连接性奖励
                score += self.advanced_adjacent_score(chips, x, y, team)[0]

            elif action['type'] == 'remove':
                # 威胁消除评估
                danger = self.calculate_danger(chips, x, y, opp_team)
                score += danger * 120 + self.center_bonus[y][x] * 30

            # 阶段调整策略
            if self.near_victory(chips, team):
                score *= 1.8  # 终局加强
            elif self.early_game(chips):
                score += self.center_bonus[y][x] * 10  # 开局重视中心

            if score > best_score:
                best_score = score
                best_action = action

        return best_action if best_action else random.choice(actions)

    def advanced_adjacent_score(self, chips, x, y, team):
        score = 0
        potential = 0
        directions = [(-1,0),(1,0),(0,-1),(0,1),(-1,-1),(1,1),(-1,1),(1,-1)]
        
        for dx, dy in directions:
            consecutive = 1
            for i in range(1, 4):
                nx, ny = x + dx*i, y + dy*i
                if 0 <= nx < 10 and 0 <= ny < 10:
                    if chips[ny][nx] == team:
                        consecutive += 1
                        score += 15 * (2 ** consecutive)  # 指数增长奖励
                    else:
                        break
            if consecutive >= 2:
                potential += 1
        return score, potential

    def evaluate_potential(self, chips, x, y, team):
        potential = 0
        directions = [(dx, dy) for dx in (-1,0,1) for dy in (-1,0,1) if (dx, dy) != (0,0)]
        
        for dx, dy in directions:
            line = []
            for i in range(-3, 4):
                nx, ny = x + dx*i, y + dy*i
                if 0 <= nx < 10 and 0 <= ny < 10:
                    line.append(chips[ny][nx])
                else:
                    line.append(None)
            
            # 检测3+1和2+2模式
            for i in range(4):
                segment = line[i:i+4]
                team_count = segment.count(team)
                empty_count = segment.count(None)
                
                if team_count == 3 and empty_count == 1:
                    potential += 2
                elif team_count == 2 and empty_count == 2:
                    potential += 1
                elif team_count == 1 and empty_count == 3:
                    potential += 0.5
                    
        return potential

    def calculate_danger(self, chips, x, y, opp_team):
        if chips[y][x] != opp_team:
            return 0
            
        danger = 0
        directions = [(-1,0),(1,0),(0,-1),(0,1),(-1,-1),(1,1),(-1,1),(1,-1)]
        
        for dx, dy in directions:
            consecutive = 0
            for i in range(4):
                nx, ny = x + dx*i, y + dy*i
                if 0 <= nx < 10 and 0 <= ny < 10:
                    if chips[ny][nx] == opp_team:
                        consecutive += 1
                    else:
                        break
            danger += {2:30, 3:100, 4:300}.get(consecutive, 0)
                
        return danger

    def near_victory(self, chips, team):
        # 根据实际胜利条件调整（通常需要2个序列）
        team_chips = sum(row.count(team) for row in chips)
        return team_chips >= 15  # 根据实际游戏调整阈值

    def early_game(self, chips):
        total_chips = sum(row.count('r') + row.count('b') for row in chips)
        return total_chips < 50  # 开局阶段判断
